<?php
class DBMSqlServerConnection extends DBMConnection {
	public function connect(){
		// try to connect
 		$this->setLink(@mssql_connect($this->getHost(), $this->getUsername(), $this->getPassword()));
 		$database = @mssql_select_db($this->getDatabase(), $this->getLink());
 		
 		// check the connection
 		if(!$this->getLink() || !$database){
 			throw new Exception("Impossible to open a connection with the host '" . $this->getHost(). ". Please check the options!");
 		}

 		// return
 		return true;
	}
	public function disconnect(){
		// check if there's an opened transaction and is autocommit
		if($this->isTransactionOpened() && $this->isTransactionAutoCommit()){
			// commit the opened transaction
			$this->commitTransaction();
		}
		
		// return
 		return true;
	}
	
	public function beginTransaction($autocommit){
		// open the transaction 
		$this->runQuery("BEGIN TRANSACTION;", false);
		
		// set the transaction as opened
		$this->setTransactionOpened(true);
		
		// set the autocommit value
		$this->setTransactionAutoCommit($autocommit);
	}
	
	public function rollbackTransaction(){
		// rollback the transaction
		$this->runQuery("ROLLBACK;", false);
	}
	
	public function commitTransaction(){
		// commit the transaction
		$this->runQuery("COMMIT;", false);
	}
	
	public function executeCommand(DBMCommand $command){
		// create the query
 		$query = DBMCommandTranslator::translateToSQLServer($command, null);
 		
 		// run the query
 		$this->runQuery($query->getQueryString(), false);
 		
 		// get the number of affected rows
 		$affectedRows = mssql_rows_affected($this->getLink());
 		
 		// return the resultset
 		return $affectedRows;
	}
	
	public function executeSelect(DBMCommand $command){
		// create the query
 		$query = DBMCommandTranslator::translateToSQLServer($command, null);
 		
 		// runs the query
 		$resultset = $this->runQuery($query->getQueryString(), true);
 		
 		// return the resultset
 		return $resultset;
	}
	public function executeInsert(DBMCommand $command){
		// create the query
 		$query = DBMCommandTranslator::translateToSQLServer($command);
 		
 		// runs the query
 		$this->runQuery($query->getQueryString(), false); 
 		
 		// get the identity of the inserted entity
 		$idResult 	= $this->runQuery("SELECT SCOPE_IDENTITY();", false);
 		$idRow		= mssql_fetch_row($idResult);
 		
		// check the integrity
 		if(!$idRow[0] || is_null($idRow[0])){
 			// get the identity of the inserted entity using @@identity
 			$idResult 	= $this->runQuery("SELECT @@IDENTITY", false);
 			$idRow		= mssql_fetch_row($idResult);
 		}
 		
 		// return
 		return $idRow[0];
	} 
	
	public function executeUpdate(DBMCommand $command){
		return $this->executeCommand($command);
	}
	
	public function executeDelete(DBMCommand $command){
		return $this->executeCommand($command);
	}
	
	public function runQuery($sql, $createResultset = false){
		// check if the cache is enabled
		if(!is_null($this->getCache())){
			// check for some cache results
			$cacheResult = $this->getCache()->get($sql);
			
			// check the result integrity
			if(!is_null($cacheResult)){
				return $cacheResult;
			}
		}
		
		// no cache for this query, execute the query in the database
		$result = @mssql_query($sql, $this->getLink());
		
		// check the result
 		if(!$result){
			$this->setErrors($this->getErrors() + 1);
			throw new SQLException(mssql_get_last_message(), DBManager::TYPE_MSSQL, $sql);
		}
		
		// increase the query count
		$this->setQueries($this->getQueries() + 1);
	
		// check if the creation of the resultset is needed
		if($createResultset){
			return $this->createResultset($sql, $result); 
		} else {
			// return the database result object
			return $result;
		}
	}
	
	public function toSQL(DBMCommand $command){
		return DBMCommandTranslator::translateToSQLServer($command)->getQueryString();
	}
	
	public function createResultset($sql, $databaseResult, $cache = true){
		// check the number of results
		if(mssql_num_rows($databaseResult) <= 0){
			throw new EmptyResultException($sql);
		}
		
		// create a new resultset
		$resultset 		= new DBMResultSet();
		$queryFields	= false;
				
		// search the results
		while($data = mssql_fetch_assoc($databaseResult)){
 			// create the result object
 			$row = new DBMResult();
 			
 			// check if the fields have been setted
 			if($queryFields == false){
 				$fields = array();
 			}

 			// search the query fields
 			foreach($data as $fieldName => $fieldValue){
 				// check if the fields have been setted
 				if($queryFields == false){
 					$fields[] = $fieldName;
 				}
 				
 				// store the value
 				$row->put($fieldName, $fieldValue);
 			}
 			
			// check if the fields have been setted
 			if($queryFields == false){
 				$queryFields = $fields;
 			}
 			
 			// store the result in the resultset
 			$resultset[] = $row;
 		}
 		
 		// set the query fields in the resultset
 		$resultset->setFields($queryFields);
 		
 		// check if the cache is enabled
 		if(!is_null($this->getCache())){
 			// store the resultset in cache
 			$this->getCache()->store($sql, $resultset);	
 		}
 		
 		// return the resultset
 		return $resultset;
	}
}
?>